package com.gameai.tickettoride.core;

import static playn.core.PlayN.*;

import playn.core.Game;
import playn.core.Image;
import playn.core.ImageLayer;
import playn.core.GroupLayer;
import playn.core.Pointer;

import java.util.ArrayList;
import java.util.HashMap;
import playn.core.CanvasImage;

public class tickettoride implements Game {
      
    static final Graph TtRgraph = new Graph();
    
    //Players
    Player playerHum;
    Player playerAI;
    
//    boolean playerInput = false;
    boolean playerTurn = true;
    boolean playerDone = false;
    
    int playerAct = 0;
    
    //GUI vars
    static GroupLayer cardLayer;
    Slot[] visibleCards;
    
    CanvasImage numTrainsImage;
    ImageLayer numTrainsLayer;
    
    CanvasImage routeImage;
    ImageLayer routeLayer;
    
    ImageLayer dCardLayer;
    
    ArrayList<int[]> routes = new ArrayList<int[]>();

    DestCard[] destCards;
    boolean destDraw = false;
    boolean[] cardsPicked = {false, false, false};
    
    //Decks
    TrainDeck trainDeck;
    DestDeck destDeck;
    
    //Card slots
    static Slot slot1; //{932, 17};
    static Slot slot2; //{932, 80};
    static Slot slot3; //{932, 144};
    static Slot slot4; //{932, 207};
    static Slot slot5; //{932, 270};
    
    final int[] trainDrawDeck = new int[]{925, 329};
    final int[] destDrawDeck = new int[]{927, 497};
    final int[] destCardSize = new int[]{114, 73};
    final int bgWidth = 1050;
    final int bgHeight = 591;
    final int[] destCardSelect = new int[]{bgWidth/2 - 227, bgHeight/2 - 40};
    final int[] destCardSelSize = new int[]{454, 80};
    
    protected static class Slot {
        
        final int[] size = {93, 60};
        int xPos;
        int yPos;
        int slotNum;
        TrainCard card;
        
        Slot(int x, int y){
            xPos = x;
            yPos = y;
        }
        
        public void setCard(TrainCard c) {
            card = c;
            ImageLayer cardImg = graphics().createImageLayer(c.IMAGE);
            cardImg.setTranslation(xPos, yPos);
            cardLayer.add(cardImg);
        }
        
        public Card getCard() {
            return card;
        }
        
    }
    
       
    public static HashMap<Graph.COLOR, Integer> getSlotColorsMap(){
        HashMap<Graph.COLOR, Integer> out = new HashMap<Graph.COLOR, Integer>();
        
        for(Graph.COLOR c: Graph.COLOR.values()){
            out.put(c, new Integer(0));
        }
        
        out.put(slot1.card.getCardColor(), out.get(slot1.card.getCardColor())+1);
        out.put(slot2.card.getCardColor(), out.get(slot2.card.getCardColor())+1);
        out.put(slot3.card.getCardColor(), out.get(slot3.card.getCardColor())+1);
        out.put(slot4.card.getCardColor(), out.get(slot4.card.getCardColor())+1);
        out.put(slot5.card.getCardColor(), out.get(slot5.card.getCardColor())+1);
        
        return out;
   }
    
    public static Graph getGraph(){
        return TtRgraph;
    }
    
    @Override
    public void init() {
        
        // create and add background image layer (1050wx591h)
        final Image bgImage = assets().getImage("images/bg.png");
        ImageLayer bgLayer = graphics().createImageLayer(bgImage);
        graphics().rootLayer().add(bgLayer);
        
        // create a group layer to hold the cards
        cardLayer = graphics().createGroupLayer();
        graphics().rootLayer().add(cardLayer);
        
        //Add numTrains layer
        numTrainsImage = graphics().createImage(50, 50);
        numTrainsLayer = graphics().createImageLayer(numTrainsImage);
        numTrainsLayer.setTranslation(130, 566);
        graphics().rootLayer().add(numTrainsLayer);
        
        //Add routes layer
        routeImage = graphics().createImage(1050, 591);
        routeImage.canvas().setStrokeColor(0xff000000);
        routeImage.canvas().setStrokeWidth(3);
        for(City[] cty : TtRgraph.getConnections().keySet()) {
            routeImage.canvas().drawLine(cty[0].x, cty[0].y, cty[1].x, cty[1].y);
            routes.add(new int[]{cty[0].x, cty[0].y, cty[1].x, cty[1].y});
        }
        routeLayer = graphics().createImageLayer(routeImage);
        graphics().rootLayer().add(routeLayer);
        
        //Instantiate Decks
        trainDeck = new TrainDeck();
        destDeck = new DestDeck();
        
        //Instantiate Players
        playerHum = new Player(false, 0);
        playerAI = new Player(true, 1);
        
        //Instantiate Slots
        slot1 = new Slot(932, 17);
        slot2 = new Slot(932, 80);
        slot3 = new Slot(932, 144);
        slot4 = new Slot(932, 207);
        slot5 = new Slot(932, 270);
        
        //Draw and Display first 5 cards
        visibleCards = new Slot[]{slot1, slot2, slot3, slot4, slot5};
        
        for(int i=0; i < 5; i++) {
            TrainCard card = (TrainCard) trainDeck.draw();
            visibleCards[i].setCard(card);
        }
        
        //Draw first 3 dest cards and present to Player
        destCards = destDeck.draw();
        System.out.println(destCards.toString());

        //Drawing in paint() method
        
        // add a listener for pointer (mouse, touch) input
        pointer().setListener(new Pointer.Adapter() {
            
            @Override
            public void onPointerEnd(Pointer.Event event) {
              // .. event.x() and event.y()
              
              //Check x (works for all slots)
              if (event.x() > slot1.xPos && event.x() < slot1.xPos + slot1.size[0]) {
                    if (event.y() > slot1.yPos && event.y() < slot1.yPos + slot1.size[1]) {
                      //Clicked Card 1
                      System.out.println("Clicked Card 1");
                      playerHum.addToHand(slot1.getCard());
                      
                      if (slot1.getCard().value == 0) {
                          playerAct += 2;
                      } else {
                          playerAct++;
                      }
                      
                      slot1.setCard(trainDeck.draw());
                    } else if (event.y() > slot2.yPos && event.y() < slot2.yPos + slot2.size[1]) {
                      //Clicked Card 2
                      System.out.println("Clicked Card 2");
                      playerHum.addToHand(slot2.getCard());
                      
                      if (slot2.getCard().value == 0) {
                          playerAct += 2;
                      } else {
                          playerAct++;
                      }
                      
                      slot2.setCard(trainDeck.draw());
                    } else if (event.y() > slot3.yPos && event.y() < slot3.yPos + slot3.size[1]) {
                      //Clicked Card 3
                      System.out.println("Clicked Card 3");
                      playerHum.addToHand(slot3.getCard());
                      
                      if (slot3.getCard().value == 0) {
                          playerAct += 2;
                      } else {
                          playerAct++;
                      }

                      slot3.setCard(trainDeck.draw());
                    } else if (event.y() > slot4.yPos && event.y() < slot4.yPos + slot4.size[1]) {
                      //Clicked Card 4
                      System.out.println("Clicked Card 4");
                      playerHum.addToHand(slot4.getCard());

                      if (slot4.getCard().value == 0) {
                          playerAct += 2;
                      } else {
                          playerAct++;
                      }
                      
                      slot4.setCard(trainDeck.draw());
                    } else if (event.y() > slot5.yPos && event.y() < slot5.yPos + slot5.size[1]) {
                      //Clicked Card 5
                      System.out.println("Clicked Card 5");
                      playerHum.addToHand(slot5.getCard());
                      
                      if (slot5.getCard().value == 0) {
                          playerAct += 2;
                      } else {
                          playerAct++;
                      }
                      
                      slot5.setCard(trainDeck.draw());
                    }
                }
              
                if (event.x() > trainDrawDeck[0] && event.x() < trainDrawDeck[0] + 93) {
                    if (event.y() > trainDrawDeck[1] && event.y() < trainDrawDeck[1] + 60) {
                      //Clicked draw deck
                      System.out.println("Clicked TrainDeck");
                      playerHum.addToHand(trainDeck.draw());
                      playerAct++;
                    }
                }
                
                //Check dest card y
                if (event.y() > destCardSelect[1] && event.y() < destCardSelect[1] + destCardSelSize[1]) {
                    //Then check dest card x's
                    if (event.x() > destCardSelect[0] && event.x() < destCardSelect[0] + destCardSize[0]) {
                        //Clicked first destCard
                        System.out.println("Clicked DestCard 1");
                        cardsPicked[0] = !cardsPicked[0];
                    } else if (event.x() > destCardSelect[0] + 126 && event.x() < destCardSelect[0] + destCardSize[0] + 126) {
                        //Clicked second destCard
                        System.out.println("Clicked DestCard 2");
                        cardsPicked[1] = !cardsPicked[1];
                    } else if (event.x() > destCardSelect[0] + 251 && event.x() < destCardSelect[0] + destCardSize[0] + 251) {
                        //Clicked third destCard
                        System.out.println("Clicked DestCard 3");
                        cardsPicked[2] = !cardsPicked[2];
                    } else if (event.x() > destCardSelect[0] + 390 && event.x() < destCardSelSize[0] + destCardSelSize[0] - 15 && event.y() > destCardSelect[1] + 15 && event.y() < destCardSelect[1] + destCardSelSize[1] - 15) {
                        //Clicked OK button
                        System.out.println("Clicked OK");
                        //Check cards picked
                        int count = 0;
                        for (int i = 0; i < 3; i++) {
                            if (cardsPicked[i] == true) {
                                count++;
                            }
                        }
                        if (count >= 2) {
                            System.out.println("Dest cards picked!");
//                            playerInput = true;
                            for(int i = 0; i < 3; i++) {
                                if(cardsPicked[i] == true)
                                    playerHum.addToHand(destCards[i]);
                            }
                            graphics().rootLayer().remove(dCardLayer);
                        } else {
                            System.out.println("Not enough cards picked!");
                        }
                    }
                }
                
                //Intersection with lines
//                for(int[] r : routes) {
//                    float x = event.x();
//                    float y = event.y();        
//                }
                
                if (playerAct >= 2) {
                    playerDone = true;
                    playerTurn = false;
                }
              
                System.out.println(playerHum.getHand());
                System.out.println(playerAI.getHand());
              
            } // End pointer event
        });
        
        //Start first player DestDraw
        destDraw = true;
        
        if(destDraw) {
            createDestCardLayer(destCards);
            destDraw = false;
        }
    }

    @Override
    public void paint(float alpha) {
        // the background automatically paints itself, so no need to do anything here!
        
        //Animate card movements
        //x += 0.1f * alpha;
        
        //Draw player number of trains left
        //via - http://proppy-playn101.appspot.com/#27
        String s = Integer.toString(playerHum.available_trains);
        numTrainsImage.canvas().clear();
        numTrainsImage.canvas().setFillColor(0xff000000);
        numTrainsImage.canvas().drawText(s, 7, 10);
    }

    @Override
    public void update(float delta) {
        
//        if(playerInput) {
//            
//        }
        
//        if(playerTurn) {
//            
//            
//        } else {
//            TtRgraph.choose_your_destiny(playerAI);
//            playerAct = 0;
//            playerTurn = true;
//        }
        
    }

    @Override
    public int updateRate() {
        return 25;
    }
    
    private void createDestCardLayer(DestCard[] cards) {

        Image destImg = assets().getImageSync("images/destCard.png");
        CanvasImage dCardImage = graphics().createImage(454, 80);
        String[] cities = new String[3];
        Integer[] scores = new Integer[3];
        
        //Draw Image
        dCardImage.canvas().drawImage(destImg, 1, 1);
        dCardImage.canvas().drawImage(destImg, 126, 1);
        dCardImage.canvas().drawImage(destImg, 251, 1);
        dCardImage.canvas().scale(0.95f, 0.95f);
        int i = 0;
        for (DestCard c : cards) {

            //System.out.println("imaging card " + c.toString());
            //Draw Text
            cities[i] = " " + c.getDestCities()[0].toString() + " - " + c.getDestCities()[1].toString() + " ";
            scores[i] = c.getScore();
            i++;
        }

        dCardImage.canvas().drawText(cities[0], 11, 12);
        dCardImage.canvas().drawText(scores[0].toString(), 91, 53);
        
        dCardImage.canvas().drawText(cities[1], 126, 12);
        dCardImage.canvas().drawText(scores[1].toString(), 216, 53);
        
        dCardImage.canvas().drawText(cities[2], 251, 12);
        dCardImage.canvas().drawText(scores[2].toString(), 341, 53);
        
        //Draw ok button
        Image buttonImg = assets().getImageSync("images/ok.png");
        dCardImage.canvas().drawImage(buttonImg, 390, 15);

        dCardLayer = graphics().createImageLayer(dCardImage);
        dCardLayer.setTranslation(bgWidth/2 - 227, bgHeight/2 - 40);
        //dCardLayer.setScale(2f);
        graphics().rootLayer().add(dCardLayer);
            
//            while (!playerInput) {
//                //Show card is selected
//                for(int i=0; i < 3; i++) {
//                    int loc = 1 + 117*i;
//                    //destCardImage.canvas().setStrokeColor(0xff00ff00);
//                    if (cardsPicked[i] == true) {
//                      //  destCardImage.canvas().strokeRect(loc, 1, destCardSize[0], destCardSize[1]);
//                    }
//                }
//            }
            
    }
    
//    public boolean intersectLine(int a1, int a2, int b1, int b2) {
//    //-- http://www.kevlindev.com/gui/math/intersection/Intersection.js
//    boolean result;
//      int ua_t = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x);
//      int ub_t = (a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x);
//      int u_b = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y);
//
//  if (u_b != 0) {
//    int ua = ua_t / u_b;
//    int ub = ub_t / u_b;
//
//    if (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) {
//        result = true;
//    } else {
//        result = false; //--"No Intersection"
//    }
//  } else {
//    if (ua_t == 0 || ub_t == 0) {
//        result = false; //-- Coincident"
//    } else {
//        result = false; //-- Parallel
//    }
//  }
//
//  return result;
//}
}